#pragma once

#include "Common.h"
#include "DelayCall.h"
#include <iostream>
#include <functional>
#include <string>
#include <vector>
#include <random>
#include <mutex>

enum PLAYER_STATE {
    ON_CARD_IN,         // 拿到牌(发牌或者吃牌得到)，UI该刷新的可以刷新
    ON_CARD_OUT_START,  // 出牌开始，通知大家注意了，UI该刷新的可以刷新
    ON_CARD_OUT_OVER,   // 出牌完成，通知下家继续，UI该刷新的可以刷新
    ON_INFO_CHANGE      // 个人信息变化，UI该刷新的可以刷新
};

template<typename T>
class BasePlayer
{
public:
    BasePlayer() {}
    virtual ~BasePlayer() {}

public:
    virtual void cardIn(int32_t card) {
        // 游戏开启前发牌, 玩家拿到牌
        this->m_cards.push_back(card);
        this->sortCards();
        this->delayNotify(PLAYER_STATE::ON_CARD_IN, card, 0.0f);
    }
    // 出牌逻辑由子类实现
    virtual void cardOut() = 0;
    // 经过思考之后出牌，玩家选择的牌在此处传回
    virtual void doCardOut(std::vector< int32_t >& data) {
        this->m_cardsLastOut.clear();
        for (int32_t& one : data) {
            std::vector<int32_t>::iterator iter = std::find(this->m_cards.begin(), this->m_cards.end(), one);
            if (iter != m_cards.end()) {
                this->m_cards.erase(iter);
            }
            this->m_cardsLastOut.emplace_back(one);
        }
        this->delayNotify(PLAYER_STATE::ON_CARD_OUT_OVER, (int32_t)m_cards.size(), 0.3f);
    }

    void addActionListener(std::function<void(const T * const, PLAYER_STATE, int32_t)> callback) {
        this->m_theListener.emplace_back(callback);
    }
    virtual void getLastOutCards(std::vector< int32_t >& arr) const {
        arr.clear();
        arr.assign(this->m_cardsLastOut.begin(), this->m_cardsLastOut.end());
    }
    virtual void getHandCards(std::vector< int32_t >& arr) const {
        arr.clear();
        arr.assign(this->m_cards.begin(), this->m_cards.end());
    }
    virtual void sortCards() {
        std::sort(this->m_cards.begin(), this->m_cards.end());
    }
    virtual bool isLocalPlayer() const {
        return this->m_local;//是不是玩家
    }
    virtual int getCardCount() const {
        return (int)this->m_cards.size();//还剩下几张牌
    }

protected:
    virtual void delayNotify(PLAYER_STATE state, int32_t card, float delayTime) = 0;

    DEFINE_PROPERTY(std::string, m_name, Name); //名字
    DEFINE_PROPERTY(uint8_t, m_sex, Sex);       //性别(0女1男2未知)
    DEFINE_PROPERTY(int32_t, m_score, Score);   //分数
    DEFINE_PROPERTY(uint8_t, m_seat, Seat);     //座位从0开始
    DEFINE_PROPERTY(bool, m_local, Local);      //本地用户,对于单机来说就是区分玩家(isLocal)和机器人,对于联网来说就是本人(isLocal)还是网络对手

protected:
    std::vector< int32_t > m_cards;// 手中的牌
    std::vector< int32_t > m_cardsLastOut;// 最后一次出的牌,留在这里,可以给别人做出牌判断用,为空就是本轮没有出牌
    std::vector< std::function<void(const T * const, PLAYER_STATE, int32_t)> >  m_theListener;
};

